package cn.agiledata.bank.linkbank.action;

import java.math.BigDecimal;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import cn.agiledata.bank.common.util.Constant;
import cn.agiledata.bank.common.util.ForeDict;
import cn.agiledata.bank.common.util.StringUtil;
import cn.agiledata.bank.common.util.WebUtil;
import cn.agiledata.bank.hibernateBean.Account;
import cn.agiledata.bank.linkbank.exception.LinkBankException;
import cn.agiledata.bank.linkbank.form.WebPayForm;
import cn.agiledata.bank.linkbank.form.WebPayRequestForm;
import cn.agiledata.bank.linkbank.logic.payment.UnsPayRequest;
import cn.agiledata.bank.linkbank.logic.payment.UnsPayResponse;
import cn.agiledata.bank.linkbank.service.BankTelPayService;
import cn.agiledata.bank.linkbank.service.FieldValidateService;
import cn.agiledata.bank.linkbank.service.WebPayService;
import com.vnv.infrastructure.action.IPBBaseAction;
import com.vnv.infrastructure.exception.IPBException;
import com.vnv.infrastructure.logic.IPBAppFactory;

public class WebPayRequestAction extends IPBBaseAction {
	private BankTelPayService bankTelPayService;

	/**
	 * 支付请求对象关键字
	 */
	public static final String UNS_PAY_REQUEST = "webPayRequest";

	/**
	 * 支付请求Form关键字
	 */
	public static final String UNS_PAY_REQUEST_FORM = "WebPayRequestForm";

	public int hasAccessPermission(int accessLevel, HttpServletRequest request)
			throws IPBException {
		return 1;
	}

	private WebPayService getWebPayService() {
		return (WebPayService) IPBAppFactory.getObj(ForeDict.SERVICE_WEB_PAY);
	}

	private BankTelPayService getBankTelPayService() {
		if (this.bankTelPayService == null) {
			this.bankTelPayService = (BankTelPayService) IPBAppFactory
					.getObj(ForeDict.SERVICE_BANK_TEL_PAY);
		}
		return this.bankTelPayService;
	}

	private FieldValidateService getFieldValidateService() {
		return (FieldValidateService) IPBAppFactory
				.getObj(ForeDict.SERVICE_FIELD_VALIDATE_SERVICE);
	}

	private void saveWebPayRequest(HttpServletRequest request,
			WebPayRequestForm form, String actionType) throws LinkBankException {
		WebPayService webPayService = getWebPayService();
		UnsPayRequest unsPayRequest = webPayService
				.getUnsPayRequest(form, null);
		if (unsPayRequest == null) {
			throw LinkBankException.LOSE_REQUEST_DATA;
		}
		if (actionType != null) {
			webPayService.setActionType(unsPayRequest, actionType);
		}
		HttpSession session = request.getSession();
		session.setAttribute(UNS_PAY_REQUEST, unsPayRequest);
	}

	private UnsPayResponse createUnsPayResponseForException(
			LinkBankException e, WebPayRequestForm form,
			HttpServletRequest request) {
		int realResponseMode = Constant.RESPONSE_MODE_NEVER; // 不返回商户页面，只在支付结果页面显示
		BigDecimal amount;
		try {
			amount = new BigDecimal(form.getAmount());
		} catch (Exception ex) {
			amount = new BigDecimal(0);
		}
		String merchantUrl = form.getMerchantUrl();
		UnsPayResponse unsPayResponse = new UnsPayResponse(
				form.getMerchantId(), form.getOrderId(), amount, merchantUrl,
				realResponseMode);
		unsPayResponse.setAccountKey(getWebPayService().getAccountKey(
				form.getMerchantId()));
		unsPayResponse.setReturnCode(e.getErrorCode());
		String returnMessage = getAppExceptionMessage(request, e);
		unsPayResponse.setReturnMessage(returnMessage);
		return unsPayResponse;
	}

	public ActionForward webPayRequest(ActionMapping mapping,
			ActionForm actionForm, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		WebPayRequestForm form = (WebPayRequestForm) actionForm;
		String flag = (String) request.getSession().getAttribute("flag");
		request.getSession().removeAttribute("flag");
		if (StringUtils.isNotBlank(flag))
			request.setAttribute("flag", "barCode");
		try {
			// 校验参数
			Map parameters = WebUtil.getRequestParameters(request);
			String version = form.getVersion();
			getFieldValidateService().validateUnsPayRequestFields(version,
					parameters);

			String merchantId = form.getMerchantId();
			String subAccountId = form.getSubAccountId();
			WebPayService webPayService = getWebPayService();
			Account account = webPayService.validateAccount(merchantId,
					subAccountId);
			String orderId = form.getOrderId();
			String transId = webPayService.validateOrderId(merchantId, orderId);
			form.setTransId(transId);
			request.setAttribute("transId", transId);
			if(version.compareTo("4.0.0") >= 0) {
				// 版本4.0.0以上版本适用证书验签
				// FIXME 提交交易证书验签
				webPayService.validateSign(parameters,form.getSign());
			}
			else {
				webPayService.validateMac(parameters, form.getMac());
			}
			
			webPayService.validateAmount(form.getAmount());
			// 参数校验完毕

			request.setAttribute("netbanklist", getWebPayService()
					.getSupportedNetBanks());// 网银列表
			request.setAttribute("telbanklist", getBankTelPayService()
					.getSupportedBanks());// 电话银行列表

			if (form.isAssured()
					&& Constant.BANK_CODE_TOPPAY.equals(form.getBankCode())) {
				saveWebPayRequest(request, form,
						Constant.ACTION_TYPE_INNER_TRANS);
				return mapping.findForward("unspay");
			}
			if (StringUtil.isStrEmpty(form.getBankCode())) {// 银行代码为空，则是账户支付
				saveWebPayRequest(request, form,
						Constant.ACTION_TYPE_INNER_TRANS);
			}

			boolean corpAccount = Constant.ACCOUNT_TYPE_CORPORATION
					.equals(account.getAccountType());
			boolean showPhoto = corpAccount && account.getPhoto() != null
					&& account.getPhoto().length() > 0;
			request.setAttribute("corpAccount", new Boolean(corpAccount));
			request.setAttribute("showPhoto", new Boolean(showPhoto));
			request.setAttribute("account", account);
			// 如果版本支持直选银行
			if (webPayService.isBankCodeSupported(version)) {
				String bankLinkCode = form.getBankCode();
				if (Constant.BANK_CODE_TOPPAY.equals(bankLinkCode)) { // 直选账户支付，跳转到账户间支付
					saveWebPayRequest(request, form,
							Constant.ACTION_TYPE_INNER_TRANS);
					return mapping.findForward("myspace");
				} else if (bankLinkCode != null && bankLinkCode.length() > 0) { // 银行代码不为空，跳转到银行支付请求
					String actionType = form.isB2b() ? Constant.ACTION_TYPE_B2B_NET_PAY
							: Constant.ACTION_TYPE_B2C_NET_PAY;

					// zln 修正 商户调用接口使用银行linkcode作为直连编号。 2008-05-12
					// 为了方便银行切换不同接口而进行此修改
					String strBankCode = webPayService
							.getBankCodeByLinkCode(bankLinkCode);
					request.setAttribute("bankCode", strBankCode);
					request.setAttribute("actionType", actionType);
					return mapping.findForward("netBank");
				}
				// 银行代码如果为空，则视为未直选银行，要求用户选择支付方式
			}
			return mapping.findForward(FORWARD_SUCCESS);
		} catch (LinkBankException e) {
			// 若校验参数出错，则返回错误信息
			UnsPayResponse unsPayResponse = createUnsPayResponseForException(e,
					form, request);
			request.setAttribute(UnsPayResponseAction.UNSPAYRESPONSE_KEY,
					unsPayResponse);
			request.setAttribute("requestErr", "yea");
			return mapping.findForward("response");
		}
	}

	public ActionForward toSelectPayMode(ActionMapping mapping,
			ActionForm actionForm, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		WebPayRequestForm form = (WebPayRequestForm) actionForm;
		String merchantId = form.getMerchantId();
		String orderId = form.getOrderId();
		String license = getWebPayService()
				.generateLicense(merchantId, orderId);
		form.setLicense(license);
		// add by cjh
		request.setAttribute("netbanklist", getWebPayService()
				.getSupportedNetBanks());// 网银列表
		request.setAttribute("telbanklist", getBankTelPayService()
				.getSupportedBanks());// 电话银行列表
		if (StringUtil.isStrEmpty(form.getBankCode())) {// 银行代码为空，则是账户支付
			saveWebPayRequest(request, form, Constant.ACTION_TYPE_INNER_TRANS);
		}
		return mapping.findForward(FORWARD_SUCCESS);
	}

	public ActionForward selectPayMode(ActionMapping mapping,
			ActionForm actionForm, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		String actionType = request.getParameter("actionType");
		if (Constant.ACTION_TYPE_B2C_NET_PAY.equals(actionType)) {
			return mapping.findForward("netBank");
		} else if (Constant.ACTION_TYPE_B2C_TEL_PAY.equals(actionType)) {
			return mapping.findForward("telBank");
		} else if (Constant.ACTION_TYPE_INNER_TRANS.equals(actionType)) {
			WebPayRequestForm form = (WebPayRequestForm) actionForm;
			try {
				saveWebPayRequest(request, form, actionType);
				return mapping.findForward("myspace");
			} catch (LinkBankException e) {
				UnsPayResponse unsPayResponse = createUnsPayResponseForException(
						e, form, request);
				unsPayResponse.setReturnCode("0301");
				request.setAttribute(UnsPayResponseAction.UNSPAYRESPONSE_KEY,
						unsPayResponse);
				return mapping.findForward("response");
			}
		} 
		return null;
	}

	/**
	 * 帐户支付,并且登陆
	 * 
	 * @param mapping
	 * @param actionForm
	 * @param request
	 * @param response
	 * @return
	 */
	public ActionForward toMyspace(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		WebPayForm theForm = (WebPayForm) actionForm;

		HttpSession session = request.getSession();
		UnsPayRequest unsPayRequest = (UnsPayRequest) session
				.getAttribute("unsPayRequest");
		if (!StringUtil.isStrEmpty(theForm.getAssuredPay())) {
			unsPayRequest.setAssuredPay(new Boolean(theForm.getAssuredPay())
					.booleanValue());
		}

		WebUtil.setSessionString(request, "modual", "pay$merchant");// session里设置modual
		return mapping.findForward("prelogin");
	}

	/**
	 * 帐户支付,已经登陆过
	 * 
	 * @param mapping
	 * @param actionForm
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public ActionForward toMyspaceHasLogin(ActionMapping mapping,
			ActionForm actionForm, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		WebPayForm theForm = (WebPayForm) actionForm;
		HttpSession session = request.getSession();
		UnsPayRequest unsPayRequest = (UnsPayRequest) session
				.getAttribute("unsPayRequest");
		if (!StringUtil.isStrEmpty(theForm.getAssuredPay())) {
			unsPayRequest.setAssuredPay(new Boolean(theForm.getAssuredPay())
					.booleanValue());
		}
		return mapping.findForward("myspace");

	}

}
